package com.ticket.sass.admin.business.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.google.gson.reflect.TypeToken;
import com.ticket.sass.admin.business.RoleBusiness;
import com.ticket.sass.admin.dto.input.role.RoleAddInput;
import com.ticket.sass.admin.dto.input.role.RoleListInput;
import com.ticket.sass.admin.dto.input.role.RolePowerSaveInput;
import com.ticket.sass.admin.dto.input.role.RoleUpdInput;
import com.ticket.sass.admin.dto.output.role.RoleListOutput;
import com.ticket.sass.admin.model.PageModel;
import com.ticket.sass.admin.service.impl.ResourceServiceImpl;
import com.ticket.sass.admin.service.impl.RoleResourceMapServiceImpl;
import com.ticket.sass.admin.service.impl.RoleServiceImpl;
import com.ticket.sass.admin.util.ModelUtil;
import com.ticket.sass.common.entity.tenant.RoleEntity;
import com.ticket.sass.common.entity.tenant.RoleResourceMapEntity;
import com.ticket.sass.common.exception.enums.ErrorCode;
import com.ticket.sass.common.exception.exception.BadRequestException;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author ywb
 * @date 2022-01-08 10:24
 */

@Service
@AllArgsConstructor
public class RoleBusinessImpl implements RoleBusiness {

    final RoleServiceImpl service;
    final ResourceServiceImpl resourceService;
    final RoleResourceMapServiceImpl roleResourceMapService;
    final ModelUtil modelUtil;



    @Override
    public PageModel<RoleListOutput> list(RoleListInput input) {
        IPage<RoleEntity> page = service.getRoles(input);
        List<RoleListOutput> outputs = modelUtil.listToList(
            page.getRecords(),
            new TypeToken<List<RoleListOutput>>(){}.getType()
        );
        outputs.forEach(output -> output.setResourceIds(roleResourceMapService.resourceIdByRoleId(output.getId())));
        ;
        
        return new PageModel<>(page.getTotal(), outputs);
    }

    @Override
    public void add(RoleAddInput input) {
        RoleEntity role = modelUtil.mapToMap(input, RoleEntity.class);
        service.save(role);
    }

    @Override
    public void upd(RoleUpdInput input) {
        if (service.countById(input.getId()) <= 0) {
            throw new BadRequestException(
                ErrorCode.RECORD_NOT_EXIST,
                ErrorCode.RECORD_NOT_EXIST.getReasonPhrase()
            );
        }
        RoleEntity role = modelUtil.mapToMap(input, RoleEntity.class);
        service.updateById(role);
    }
    
    @Override
    public void savePower(RolePowerSaveInput input) {
        if (service.countById(input.getRoleId()) <= 0) {
            throw new BadRequestException(
                ErrorCode.INPUT_REQUEST,
                "该角色不存在"
            );
        }
        List<Long> addIds = input.getResourceIds();
        Long realCount = resourceService.countByIds(addIds);
        if (realCount != addIds.size()) {
            throw new BadRequestException(
                ErrorCode.INPUT_REQUEST,
                "上传的资源ID有误"
            );
        }
        
        // 查出角色当前有的权限 去除上传与数据库中有的 即要删除的
        List<Long> delIds = roleResourceMapService.resourceIdByRoleId(input.getRoleId());
        // 查出上传数据  在数据库存在的
        List<Long> realIds = roleResourceMapService.resourceIdByRole(input.getRoleId(), addIds);
        
        // 当前拥有的 减去 上传与数据库都有的 即是要删除的数据
        delIds.removeAll(realIds);
        // 上传的 减去 上传与数据库都有的 即是要新增的数据
        addIds.removeAll(realIds);
        
        // 先删除
        roleResourceMapService.delRoleResource(input.getRoleId(), delIds);
        
        List<RoleResourceMapEntity> list = addIds.stream().map(id -> new RoleResourceMapEntity(input.getRoleId(), id)).collect(Collectors.toList());
        roleResourceMapService.saveBatch(list);
    }

}
